#ifndef FFT_H
#define FFT_H

#include <math.h>
#include "complex.h"

/* fff_s.h: declarations file for the fast fourier transform module.
Written by Aleksey Kalinovich, Lomonosow Moscow State University, Faculty of Physics 2010-2022.
Permission granted to use this code in any fashion provided
that this notice is retained and any alterations are
labeled as such. */

// Fast 1D Fourier transform
void fft(complex *in, complex *out, int N);
void fftr(complex *in, complex *out, int N);

// Data for repeated fast Fourier transform
// initial fftdata data(int Dimension);
struct fftdata
{
    int N, n, *f;
    complex ***c, ***cr, *t1, *t2;
    fftdata(int);
    ~fftdata(void);
}; // fftdata----------------------------------
// initial fftdata2D data(int Dimension1,int Dimension2);

struct fftdata2D
{
    int N1, N2, n1, n2, *f1, *f2;
    complex ***c1, ***cr1, ***c2, ***cr2, *t1, *t2;
    fftdata2D(int, int);
    ~fftdata2D(void);
}; // fftdata2D---------------------------

// initial fftdata3D data(int Dimension1,int Dimension2,int Dimension3);
struct fftdata3D
{
    int N1, N2, N3, n1, n2, n3, *f1, *f2, *f3;
    complex ***c1, ***cr1, ***c2, ***cr2, ***c3, ***cr3, *t1, *t2;
    fftdata3D(int, int, int);
    ~fftdata3D(void);
}; // fftdata3D----------------------------------

// Repeated fast Fourier transform
void fft_rep(complex *in, complex *out, fftdata *data);
void fftr_rep(complex *in, complex *out, fftdata *data);
void fft2D_rep(complex *in, complex *out, fftdata2D *data, int = 1, int = 1);
void fftr2D_rep(complex *in, complex *out, fftdata2D *data, int = 1, int = 1);
void fft3D_rep(complex *in, complex *out, fftdata3D *data, int = 1, int = 1, int = 1);
void fftr3D_rep(complex *in, complex *out, fftdata3D *data, int = 1, int = 1, int = 1);

int factorization(int N, int *&f);
#endif 